package com.taormina.searchservice;

import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.List;

import org.apache.http.client.ClientProtocolException;
import org.jdom.Document;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.output.XMLOutputter;
import org.xhtmlrenderer.simple.ImageRenderer;
import org.xhtmlrenderer.util.FSImageWriter;

import com.taormina.search.schema.SearchResponse;

public abstract class AbstractSearchService implements SearchService {

	@Override
	public SearchResponse getSearchResults(String query1, String query2, String query3) throws IOException, JDOMException {
		
		InputStream responseStream = null;
		File xhtmlMarkup = null;
		try {
			responseStream = getWebSearch(query1, query2, query3);
			xhtmlMarkup = launderMarkup(responseStream);
		} finally {
			responseStream.close();
		}
		
		List<String> topSearchLinks = getTopSearchLinks(xhtmlMarkup);
			
		byte[] image = renderMarkupToImage(xhtmlMarkup);
			
		xhtmlMarkup.delete();
			
		SearchResponse response = new SearchResponse();
		response.setImage(image);
		response.getLinks().addAll(topSearchLinks);
		return response;
	}
	
	protected File launderMarkup(InputStream messyMarkup) throws IOException, JDOMException {
		
		BufferedReader reader = new BufferedReader(new InputStreamReader(messyMarkup));

		SAXBuilder builder = new SAXBuilder("org.ccil.cowan.tagsoup.Parser");
		Document doc = null;
		try {
			doc = builder.build(reader);
		} finally {
			reader.close();
		}
		
		File file = File.createTempFile("searchxml", null);
		OutputStream out = new FileOutputStream(file);
		
		XMLOutputter outputter = new XMLOutputter();
		try {
			outputter.output(doc, out);
		} finally {
			out.close();
		}
		
		return file;
	}
	
	protected byte[] renderMarkupToImage(File markup) throws IOException {

		File temp = File.createTempFile("tmp-img", null);
		BufferedImage buff = ImageRenderer.renderToImage(markup, temp.getPath(), 1024);
		FSImageWriter writer = new FSImageWriter();
		ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
		buff.flush();
		byte[] image = null;
		try {
			writer.write(buff, byteStream);
			image = byteStream.toByteArray();
		} finally {
			temp.delete();
		}
		
		return image;
	}
	
	protected String fileToString(File file) throws IOException {
		BufferedReader reader = new BufferedReader(new FileReader(file));
		StringBuilder stringBuilder = new StringBuilder();
		String line;
		while ((line = reader.readLine()) != null) {
			stringBuilder.append(line);
		}
		reader.close();
		return stringBuilder.toString();
	}

	abstract InputStream getWebSearch(String query, String query2, String query3) throws ClientProtocolException, IOException;
	
	abstract List<String> getTopSearchLinks(File xhtmlMarkup) throws IOException;
	
	abstract String getSearchUrl();
	
	abstract String getQueryPrefix();
}
